package com.aramco.fion.util
{
	import com.aramco.fion.model.FlexConstants;
	
	import mx.collections.ArrayCollection;
	import mx.controls.DateField;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumnGroup;
	import mx.controls.dataGridClasses.DataGridColumn;
	
	public class BSPAdminDataModelOO
	{
		
		public var xmlData:XML;
		public var metaData:ArrayCollection = new ArrayCollection(); ;
		public var repotData:ArrayCollection = new ArrayCollection();; 
		public var hierarchyMeta:Array = new Array();
		public var paginationData:Object;
		
		public var advDataGridColumns:Array;
		public var dataGridColumns:Array;
		
		private var fieldsWithKey:Array = new Array();
		
		
		
		
		public function BSPAdminDataModelOO(xml:XML)
		{
			if(xml != null)
			{
				xmlData = xml; 
				getMetaData2(xmlData.descendants('META'));
				getReportData(xmlData.descendants('OUTPUT'));
				//getPaginationData(xmlData.descendants('PAGING_INFO'));
				getDatagridColumns(repotData, metaData);
			}
		}
		
		public function parse(xml:XML)
		{
			/*xmlData = xml; 
			getMetaData2(xmlData.descendants('META'));
			getReportData(xmlData.descendants('OUTPUT'));
			getPaginationData(xmlData.descendants('PAGING_INFO'));
			getDatagridColumns(repotData, metaData);*/
		}
		
		private function getMetaData(xml:XMLList):void
		{
			var obj:Object ;
			for each ( var itemNode : Object in xml.descendants('ITEM'))
			{
				obj = new Object();
				obj.FIELDNAME = itemNode.FIELDNAME.toString();
				obj.OUTPUTLEN = itemNode.OUTPUTLEN.toString();
				obj.DATATYPE = itemNode.DATATYPE.toString();
				obj.SCRTEXT_L = (itemNode.SCRTEXT_L.toString() != "")? itemNode.SCRTEXT_L.toString(): itemNode.FIELDNAME.toString();
				obj.AXIS_TYPE = itemNode.AXIS_TYPE.toString();
				obj.TYPE = itemNode.TYPE.toString();
				obj.ELEM = itemNode.ELEM.toString();
				metaData.addItem(obj);
			}	
		}
		
		
		private function getMetaData2(xml:XMLList):void
		{
			var obj:Object ;
			var hierarchyMetaObject:Object;
			for each ( var itemNode : Object in xml.elements('ITEM'))
			{
				obj = new Object();
				//obj.FIELDNAME = CommonActions.stripCharacteristicName(itemNode.FIELDNAME.toString());
				obj.FIELDNAME = itemNode.FIELDNAME.toString();
				
				obj.OUTPUTLEN = itemNode.OUTPUTLEN.toString();
				obj.DATATYPE = itemNode.DATATYPE.toString();
				obj.SCRTEXT_L = (itemNode.SCRTEXT_L.toString() != "")? itemNode.SCRTEXT_L.toString(): itemNode.FIELDNAME.toString();
				metaData.addItem(obj);
			}
		}
		
		
		private function getReportData(xml:XMLList):void
		{
			var obj:Object;
			var x:int = 0;
			for each ( var itemNode : XML in xml.descendants('ITEM'))
			{
				var tmp:XMLList = itemNode.children();
				obj = new Object();
				for(var i:int = 0; i < tmp.length(); i++)
				{
					var obj2:XML = tmp[i];
					if(obj2.toString() != "")
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	obj2.toString();
						obj[obj2.name().localName] =	obj2.toString();
					else
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	"#";
						obj[obj2.name().localName] =	"#";
				}
				repotData.addItem(obj);
			}
		}
		public static function getFormated(xml:XMLList):ArrayCollection
		{
			var obj:Object;
			var x:int = 0;
			var repotData:ArrayCollection = new ArrayCollection();
			for each ( var itemNode : XML in xml.descendants('item'))
			{
				var tmp:XMLList = itemNode.children();
				obj = new Object();
				for(var i:int = 0; i < tmp.length(); i++)
				{
					var obj2:XML = tmp[i];
					if(obj2.toString() != "")
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	obj2.toString();
						obj[obj2.name().localName] =	obj2.toString();
					else
						//obj[CommonActions.stripCharacteristicName(obj2.name().localName)] =	"#";
						obj[obj2.name().localName] =	"#";
				}
				repotData.addItem(obj);
			}
			return repotData;
		}
		
		private function isKeyField(str:String):Boolean
		{
			for(var i:int = 0 ; i < fieldsWithKey.length; i++)
			{
				if(str == fieldsWithKey[i].KEY)
				{
					return true;
					break;
				}
			}
			return  false;
		}
		
		private function getKeyField(str:String):String
		{
			for(var i:int = 0 ; i < fieldsWithKey.length; i++)
			{
				if(str == fieldsWithKey[i].LABEL)
				{
					return fieldsWithKey[i].KEY;
					break;
				}
			}
			return  "";
		}
		
		public function getGridDataProvider():Object
		{
			return repotData;
		}
		
		public function getDatagridColumns(outputXMLReportData:ArrayCollection, signature:ArrayCollection):void
		{
		//	myView = event.data.view;
		//	myView.bar1.removeAllChildren();
		//	var signature:ArrayCollection = _CommonModel.outputXMLReportMetaData;
			var myColumns:Array = new Array();
			var myColumns2:Array = new Array();
			var searchFieldBarIndex=-1;
			if(signature!=null)
			{
				myColumns = new Array();
				for(var i:int = 0; i < signature.length; i++)
				{
					var adgcg:AdvancedDataGridColumnGroup;
					var dgcol:DataGridColumn;
					var advDgColumn:AdvancedDataGridColumn;
						searchFieldBarIndex++;
						
						var advDgColumn:AdvancedDataGridColumn = new AdvancedDataGridColumn();
						var dgcol:DataGridColumn = new DataGridColumn();
						
						advDgColumn.dataField = (signature[i]).FIELDNAME;
						dgcol.dataField = (signature[i]).FIELDNAME;
						
						advDgColumn.headerText = (signature[i]).SCRTEXT_L;	
						dgcol.headerText = (signature[i]).SCRTEXT_L;	
						
						//Getting column width based on the content
						advDgColumn.width = getMaxColumWidth2(advDgColumn.dataField, getMaxHeaderWidth(signature, i), outputXMLReportData);
						advDgColumn.minWidth = advDgColumn.width/4;
						advDgColumn.headerWordWrap = true;
						
						dgcol.width = getMaxColumWidth2(advDgColumn.dataField, getMaxHeaderWidth(signature, i), outputXMLReportData);
						dgcol.minWidth = advDgColumn.width/4;
						dgcol.headerWordWrap = true;
						
						//Adding sorting functionality based on data type
						if(advDgColumn.sortable)
						{
							if(signature[i]['DATATYPE'] == 'NUMC' && (signature[i]['FIELDNAME'] as String).indexOf('CALMO') != -1)
								advDgColumn.sortCompareFunction = fieldCallMonthSorter((signature[i]).FIELDNAME);
								
							else if(signature[i]['DATATYPE'] == 'NUMC' ||
								signature[i]['DATATYPE'] == 'QUAN' || 
								signature[i]['DATATYPE'] == 'INT4' || 
								signature[i]['DATATYPE'] == 'CURR')
								advDgColumn.sortCompareFunction = fieldNumericSorter((signature[i]).FIELDNAME);
								
							else if(signature[i]['DATATYPE'] == 'DATS')
								advDgColumn.sortCompareFunction = fieldDateSorter((signature[i]).FIELDNAME);
							else if(signature[i]['DATATYPE'] == 'CHAR' && (signature[i]['FIELDNAME'] as String).indexOf('VALUE') != -1)
								advDgColumn.sortCompareFunction = fieldNumericSorter((signature[i]).FIELDNAME);
						}
						
						//Adding sorting functionality based on data type
						if(dgcol.sortable)
						{
							if(signature[i]['DATATYPE'] == 'NUMC' && (signature[i]['FIELDNAME'] as String).indexOf('CALMO') != -1)
								dgcol.sortCompareFunction = fieldCallMonthSorter((signature[i]).FIELDNAME);
								
							else if(signature[i]['DATATYPE'] == 'NUMC' ||
								signature[i]['DATATYPE'] == 'QUAN' || 
								signature[i]['DATATYPE'] == 'INT4' || 
								signature[i]['DATATYPE'] == 'CURR')
								dgcol.sortCompareFunction = fieldNumericSorter((signature[i]).FIELDNAME);
								
							else if(signature[i]['DATATYPE'] == 'DATS')
								dgcol.sortCompareFunction = fieldDateSorter((signature[i]).FIELDNAME);
							else if(signature[i]['DATATYPE'] == 'CHAR' && (signature[i]['FIELDNAME'] as String).indexOf('VALUE') != -1)
								dgcol.sortCompareFunction = fieldNumericSorter((signature[i]).FIELDNAME);
						}
						
						myColumns2.push(dgcol);
						myColumns.push(advDgColumn);
				}
			}
			advDataGridColumns = myColumns;
			dataGridColumns = myColumns2;
		}
		
		
		private function getMaxHeaderWidth(singnature:ArrayCollection, index:int):int
		{
			var a:Object = singnature[index];
			var currentLength:int = a.SCRTEXT_L.length;
			
			if(a.hasOwnProperty('HEADERS_INFO'))
			{
				for(var i:int=0; i < a.HEADERS_INFO.length; i++)
				{
					if(a.HEADERS_INFO[i].SCRTEXT_L.length > currentLength)
						currentLength = a.HEADERS_INFO[i].SCRTEXT_L.length; 
				}
			}
			
			return currentLength;
		}
		
		/**
		 * This function will return the with of the last datagrid column on the right.
		 * @return : column width (Number)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		protected function getMaxColumWidth2(dataField:String, headerLength:int, myData:ArrayCollection):int
		{
			var maxLength:int = 0;
			const STATIC_WIDTH:Number = 6.2;
			for(var a:int = 0; a < myData.length; a++)
			{
				var str:String = myData[a][dataField];
				if(str == null)
					str = "#";
				
				if(str.length > maxLength)
				{
					maxLength = str.length;
				}
			}
			
			if(maxLength == 0)
			{
				maxLength = STATIC_WIDTH * headerLength  * 1.5;
			}
				
			else if(maxLength == headerLength)
			{	
				maxLength = STATIC_WIDTH * headerLength * 1.5;
			}
				
				
			else if( headerLength > maxLength)
			{
				if((headerLength /1.3) > maxLength)
					maxLength = STATIC_WIDTH * headerLength *1.7;
				else
					maxLength = STATIC_WIDTH * maxLength * 1.5;
			}
				
			else
			{
				maxLength = STATIC_WIDTH * maxLength * 1.5;
			}
			
			return maxLength;
		}
		
		
		/**
		 * This function is the default function used by the datagrid in 
		 * sorting the columns that has callmonth values
		 * @param : field (string to be sorted in datagrid)
		 * @return : True (matched), Flas (unmatched)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		private function fieldCallMonthSorter(field:String):Function {
			var regEx:RegExp =  /[\/|.|-]/g;
			return function (obj1:Object, obj2:Object):int 
			{
				var var1:Array =  ((obj1[field]).toString()).split(regEx);
				var var2:Array =  ((obj2[field]).toString()).split(regEx);
				var c1:Number;
				var c2:Number;
				
				if(var1.length == 2)
					c1 = var1[0] * 12 + var1[1]*365;
				else
					c1 = 0;
				
				if(var2.length == 2)
					c2 = var2[0] * 12 + var2[1]*365;
				else
					c2 = 0;
				
				var num:Number = c1 - c2;
				return (num > 0) ? 1 : ((num < 0) ? -1 : 0);
			}
		}
		
		/**
		 * This function is the default function used by the datagrid in 
		 * sorting the columns that has NUMC, QUAN or CURR  data type
		 * @param : field (string to be sorted in datagrid)
		 * @return : True (matched), Flas (unmatched)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		private function fieldNumericSorter(field:String):Function {
			return function (obj1:Object, obj2:Object):int 
			{
				var a1:String  = ((obj1[field]).toString()).replace(FlexConstants.CURRENCY_REGULAR_EXPRISSION, "");
				var a2:String  = ((obj2[field]).toString()).replace(FlexConstants.CURRENCY_REGULAR_EXPRISSION, "");
				if(a1 == '' || a1=='#') a1 = 0;
				if(a2 == '' || a2=='#') a2 = 0;
				var num:Number = ((Number)(a1) - (Number)(a2));
				return (num > 0) ? 1 : ((num < 0) ? -1 : 0);
			}
		}
		
		/**
		 * This function is the default function used by the datagrid in 
		 * sorting the columns that has DATS data type
		 * @param : field (string to be sorted in datagrid)
		 * @return : True (matched), Flas (unmatched)
		 * @exception:
		 * @author: Mohammed H Al-Darwish
		 **/
		private function fieldDateSorter(field:String):Function {
			return function (obj1:Object, obj2:Object):int 
			{
				var a1:String = (obj1[field]).toString();
				var a2:String = (obj2[field]).toString();
				
				var d1:Date = (DateField.stringToDate(a1,FlexConstants.DATE_FORMAT));
				var d2:Date = DateField.stringToDate(a2,FlexConstants.DATE_FORMAT);
				
				if(d1 == null)
					d1 = new Date('1899','01','01');
				if(d2 == null)
					d2 = new Date('1899','01','01');
				
				var c1:Number = d1.date + d1.month*30 + d1.fullYear*365 ; 
				var c2:Number = d2.date + d2.month*30 + d2.fullYear*365 ; 
				
				var num:Number = ((Number)(c1) - (Number)(c2));
				return (num > 0) ? 1 : ((num < 0) ? -1 : 0);
			}
		}
	}
}